﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace URM_SVN
{

    public partial class Form1 : Form
    {
        private Daemon backGround;
        private LogWin log;
        private System.Collections.Generic.List<System.Windows.Forms.Label> RegisterStateBeforeOperate;
        private System.Collections.Generic.List<System.Windows.Forms.Label> RegisterStateAfterOperate;
        private static Color BackColorRegisterToZero = Color.Aqua;
        private static Color BackColorRegisterRead = Color.SpringGreen;
        private static Color BackColorRegisterWrite = Color.Red;
        private static Color BackColorRegisterAddByOne = Color.CornflowerBlue;
        private static Color BackColorRegisterDefault = Color.Silver;


        public Form1()
        {
            InitializeComponent();
            backGround = new Daemon();
            log = new LogWin();



            backGround.EventRegisterOperate += new ShowRegisterChange(registerChanges);
            backGround.EventPrepareDoInstruction += new ShowInstruction(showIntroduction);
            backGround.EventReloadInstruction += new EventHandler(backGround_EventReloadInstruction);
            backGround.EventAddInstruction += new SendToForm(backGround_EventAddInstruction);
            backGround.EventPrintf += new SendToForm(backGround_EventPrintf);
            backGround.Error += new SendToForm(backGround_Error);
            backGround.EventSetStartFinish += new EventHandler(backGround_EventSetStartFinish);
            backGround.EventSetRegisterStatus += new ShowURMstatus(backGround_EventSetRegisterStatus);


            RegisterStateBeforeOperate = new List<Label>();
            RegisterStateBeforeOperate.Add(this.label1);
            RegisterStateBeforeOperate.Add(this.label2);
            RegisterStateBeforeOperate.Add(this.label3);
            RegisterStateBeforeOperate.Add(this.label4);
            RegisterStateBeforeOperate.Add(this.label5);
            RegisterStateBeforeOperate.Add(this.label6);
            RegisterStateBeforeOperate.Add(this.label7);
            RegisterStateBeforeOperate.Add(this.label8);
            RegisterStateBeforeOperate.Add(this.label9);
            RegisterStateBeforeOperate.Add(this.label10);
            RegisterStateBeforeOperate.Add(this.label11);
            RegisterStateBeforeOperate.Add(this.label12);
            RegisterStateBeforeOperate.Add(this.label13);
            RegisterStateBeforeOperate.Add(this.label14);
            RegisterStateBeforeOperate.Add(this.label15);
            RegisterStateBeforeOperate.Add(this.label16);

            RegisterStateAfterOperate = new List<Label>();
            RegisterStateAfterOperate.Add(this.label17);
            RegisterStateAfterOperate.Add(this.label18);
            RegisterStateAfterOperate.Add(this.label19);
            RegisterStateAfterOperate.Add(this.label20);
            RegisterStateAfterOperate.Add(this.label21);
            RegisterStateAfterOperate.Add(this.label22);
            RegisterStateAfterOperate.Add(this.label23);
            RegisterStateAfterOperate.Add(this.label24);
            RegisterStateAfterOperate.Add(this.label25);
            RegisterStateAfterOperate.Add(this.label26);
            RegisterStateAfterOperate.Add(this.label27);
            RegisterStateAfterOperate.Add(this.label28);
            RegisterStateAfterOperate.Add(this.label29);
            RegisterStateAfterOperate.Add(this.label30);
            RegisterStateAfterOperate.Add(this.label31);
            RegisterStateAfterOperate.Add(this.label32);


        }

        void backGround_EventSetRegisterStatus(Urm _urm )
        {

            int[] a = new int[16];
            int [] array = _urm.GetAll();
            this.setRegisterBeforeOperate(a);
            for (int i = 0; i < array.Length; i++)
            {
                RegisterStateBeforeOperate[i].Text = array[i].ToString();
            }


        }

        void backGround_EventSetStartFinish(object sender, EventArgs e)
        {
            this.showIntroduction(0, new Instruction(), new Urm());
        }

        void backGround_Error(string _text)
        {
            MessageBox.Show(_text);
        }

        void backGround_EventPrintf(string _show)
        {
            log.AddLog(_show);
        }

        void backGround_EventReloadInstruction(object sender, EventArgs e)
        {
            this.richTextBox1.Text = "";
        }

        void backGround_EventAddInstruction(string _text)
        {
            this.richTextBox1.AppendText(_text + "\n");
        }



        private void registerChanges(int _index, ref int value, RegisterOperateType _op)
        {
            if (_index > 16)
            {
                MessageBox.Show("Max Register count is 16 now");
            }
            switch (_op)
            {
                case RegisterOperateType.Read:
                    value = readFrom(_index);
                    return;
                case RegisterOperateType.ToZero:
                    toZero(_index);
                    return;
                case RegisterOperateType.Write:
                    writeIn(_index, value);
                    return;
                case RegisterOperateType.Increase:
                    addByOne(_index);
                    return;
                default:
                    return;
            }
        }

        private void toZero(int _index)
        {
            RegisterStateBeforeOperate[_index - 1].BackColor = BackColorRegisterToZero;
            RegisterStateAfterOperate[_index - 1].BackColor = BackColorRegisterToZero;

            RegisterStateAfterOperate[_index - 1].Text = "0";
        }

        private int readFrom(int _index)
        {
            RegisterStateBeforeOperate[_index - 1].BackColor = BackColorRegisterRead;
            RegisterStateAfterOperate[_index - 1].BackColor = BackColorRegisterRead;

            return Convert.ToInt32(RegisterStateBeforeOperate[_index - 1].Text);
        }

        private void writeIn(int _index, int _value)
        {
            RegisterStateBeforeOperate[_index - 1].BackColor = BackColorRegisterWrite;
            RegisterStateAfterOperate[_index - 1].BackColor = BackColorRegisterWrite;
            RegisterStateAfterOperate[_index - 1].Text = _value.ToString();
        }

        private void addByOne(int _index)
        {
            RegisterStateBeforeOperate[_index - 1].BackColor = BackColorRegisterAddByOne;
            RegisterStateAfterOperate[_index - 1].BackColor = BackColorRegisterAddByOne;

            string tempS = RegisterStateBeforeOperate[_index - 1].Text;

            tempS = (Convert.ToInt32(tempS) + 1).ToString();

            RegisterStateAfterOperate[_index - 1].Text = tempS;

            return;
        }

        private void setRegisterBeforeOperate(int[] _registerState)
        {
            for (int i = 0; i < 16; i++)
            {
                RegisterStateBeforeOperate[i].BackColor = BackColorRegisterDefault;
                RegisterStateAfterOperate[i].BackColor = BackColorRegisterDefault;
                if (i < _registerState.Length)
                {
                    RegisterStateBeforeOperate[i].Text = _registerState[i].ToString();
                    RegisterStateAfterOperate[i].Text = _registerState[i].ToString();
                }
            }

            return;
        }

        private void showIntroduction(int _index, Instruction _instruction, Urm _registerState)
        {
            string show;
            highLightText(_index);

            if (_index == 0)
            {
                this.textBox1.Text = "";
                return;
            }

            switch (_instruction.Command)
            {
                case CommandType.Z:
                    show = "Z( " + _instruction.FirstIndex + " )";
                    break;
                case CommandType.S:
                    show = "S( " + _instruction.FirstIndex + " )";
                    break;
                case CommandType.T:
                    show = "T( " + _instruction.FirstIndex + " , " + _instruction.SecondIndex + " )";
                    break;
                case CommandType.J:
                    show = "J( " + _instruction.FirstIndex + " , " + _instruction.SecondIndex + " , " + _instruction.ThirdIndex + " )";
                    break;

                default:
                    return;     
            }

            this.setRegisterBeforeOperate(_registerState.GetAll());
            this.textBox1.Text = show;
            return;
        }

        private void resetHighLight()
        {
            richTextBox1.SelectAll();
            richTextBox1.SelectionBackColor = Color.White;
        }

        private void highLightText( int _commandIndex )
        {
            int lineIndex = _commandIndex - 1;
            resetHighLight();
            if (lineIndex < 0)
            {
                return;
            }
            richTextBox1.Select(richTextBox1.GetFirstCharIndexFromLine(lineIndex), richTextBox1.Lines[lineIndex].Length);
            richTextBox1.SelectionBackColor = Color.Lime;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            log.Show();
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            backGround.loadFile(openFileDialog1.FileName);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.openFileDialog1.ShowDialog();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            backGround.setStart();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            backGround.StepByStep();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            backGround.DoAll();
        }




    }
}
